/**
 * Created by jinxs on 14-7-22.
 * 基于easyui.tabs源码
 * 依赖
 * ui.core.js
 * ui.panel.js
 */
(function ($) {
    /**
     * 缓存名称
     * @type {string}
     * @private
     */
    var _cacheName = 'uiTabs';
    /**
     * @class 标签页组件
     * @requires {@link uiPanel}
     * @constructor uiTabs
     * @summary 构造函数
     * @param [options] {Object|String} 组件配置参数|要调用的组件方法名
     * @param [param] {Object} 表示要调用的组件方法的参数
     * @example
     *  //采用默认值
     * $('#tab').uiTabs();
     * //设置组件参数
     *  $('#tab').uiTabs({height:'20',width:'auto'});
     * //调用组件方法
     * $('#tab').uiTabs('close','');
     */
    $.fn.uiTabs = function (options, param) {
        if (typeof options == 'string') {
            return $.fn.uiTabs.methods[options](this, param);
        }
        return this.each(function () {
            var me = $(this);
            var cache = me.data(_cacheName);

            options = options || {};
            if (cache) {
                $.extend(cache.options, options);
            } else {
                me.data(_cacheName, {
                    options: $.extend({}, $.fn.uiTabs.defaults, me.parseUIConfig(), options),
                    tabs: [],
                    selectHis: []
                });
                _init(me);
            }
            _setProperties(me);
            _setSize(me);
            _bindEvents(me);
            _doFirstSelect(me);
        });
    };
    /**
     * 方法
     * @lends uiTabs.prototype
     */
    $.fn.uiTabs.methods = {
        /**
         * @summary 获得组件的配置对象
         * @name uiTabs#options
         * @function
         * @returns {Object} 组件的配置对象
         */
        options: function (target) {
            var opts = $.data(target[0], _cacheName).options;
            var tab = _getSelectedTab(target);
            opts.selected = tab ? _getTabIndex(target, tab) : -1;
            return opts;
        },
        /**
         * @summary 获得组件
         * @name uiTabs#tabs
         * @function
         * @returns {jQuery} 组件对象
         */
        tabs: function (target) {
            return $.data(target[0], _cacheName).tabs;
        },
        /**
         * @summary 设置组件的大小
         * @name uiTabs#resize
         * @function
         * @returns {jQuery} 方法调用者
         */
        resize: function (target) {
            _setSize(target);
            _setSelectedSize(target);
            return target;
        },
        /**
         * @summary 添加标签页
         * @name uiTabs#add
         * @function
         * @param options {Object} 标签页配置参数
         * @returns {jQuery} 组件对象
         */
        add: function (target, options) {
            _addTab(target, options);
            return target;
        },
        /**
         * @summary 关闭标签页
         * @name uiTabs#close
         * @function
         * @param which {Number} 标签页索引
         * @returns {jQuery} 组件对象
         */
        close: function (target, which) {
            _closeTab(target, which);
            return target;
        },
        /**
         * @summary 获得指定标签页
         * @name uiTabs#getTab
         * @function
         * @param which {Number} 标签页索引
         * @returns {Object} 标签页组件
         */
        getTab: function (target, which) {
            return _getTab(target, which);
        },
        /**
         * @summary 获得标签页Index
         * @name uiTabs#getTabIndex
         * @function
         * @param tab {Object} 需要获取Index的标签页
         * @returns {Object} 标签页组件
         */
        getTabIndex: function (target, tab) {
            return _getTabIndex(target, tab);
        },
        /**
         * @summary 获得已选择的标签页
         * @name uiTabs#getSelected
         * @function
         * @returns {Object} 标签页组件
         */
        getSelected: function (target) {
            return _getSelectedTab(target);
        },
        /**
         * @summary 选择指定的标签页
         * @name uiTabs#select
         * @function
         * @param which {Number} 标签页索引
         * @returns {jQuery} 组件对象
         */
        select: function (target, which) {
            _selectTab(target, which);
            return target;
        },
        /**
         * @summary 取消选择指定的标签页
         * @name uiTabs#unselect
         * @function
         * @param which {Number} 标签页索引
         * @returns {jQuery} 组件对象
         */
        unselect: function (target, which) {
            _unselectTab(target, which);
            return target;
        },
        /**
         * @summary 是否存在指定的标签页
         * @name uiTabs#exists
         * @function
         * @param which {Number} 标签页索引
         * @returns {jQuery} 组件对象
         */
        exists: function (target, which) {
            return _exists(target, which);
        },
        /**
         * @summary 更新标签页
         * @name uiTabs#update
         * @function
         * @param options {Object} 标签页配置参数
         * @returns {jQuery} 组件对象
         */
        update: function (target, options) {
            _updateTab(target, options, true);
            return target;
        },
        /**
         * @summary 启用指定标签页
         * @name uiTabs#enableTab
         * @function
         * @param which {Number} 标签页索引
         * @returns {jQuery} 组件对象
         */
        enableTab: function (target, which) {
            var tab = target.uiTabs('getTab', which).uiPanel('options').tab;
            tab.removeClass('tabs-disabled');
            return target;
        },
        /**
         * @summary 禁用指定标签页
         * @name uiTabs#disableTab
         * @function
         * @param which {Number} 标签页索引
         * @returns {jQuery} 组件对象
         */
        disableTab: function (target, which) {
            var tab = target.uiTabs('getTab', which).uiPanel('options').tab;
            tab.addClass('tabs-disabled');
            return target;
        },
        /**
         * @summary 根据偏移量滚动
         * @name uiTabs#scrollBy
         * @function
         * @param deltaX 偏移量
         * @returns {jQuery} 组件对象
         */
        scrollBy: function (target, deltaX) {
            var opts = target.uiTabs('options');
            var targetID = target.getElemID();
            var headerTabs = $.getByParentID(targetID, $.uiTemplate.tabs.headerCenter);
            var pos = Math.min(headerTabs.scrollLeft() + deltaX, getMaxScrollWidth());
            headerTabs.animate({scrollLeft: pos}, opts.scrollDuration);

            function getMaxScrollWidth() {
                var width = 0;
                var ul = $.getByParentID(targetID, $.uiTemplate.tabs.headerTabs);
                ul.children('li').each(function () {
                    width += $(this).outerWidth(true);
                });
                return width - headerTabs.width() + (ul.outerWidth() - ul.width());
            }
        }
    };
    /**
     * 默认配置
     * @lends uiTabs.prototype
     */
    $.fn.uiTabs.defaults = {
        /**
         * @type Number
         * @default 0
         * @summary 组件宽度
         */
        width: 0,
        /**
         * @type Number
         * @default 0
         * @summary 组件高度
         */
        height: 0,
        /**
         * @type Number
         * @default 150
         * @summary 组件标头宽度
         */
        headerWidth: 150,
        /**
         * @type String
         * @default auto
         * @summary 标签宽度
         */
        tabWidth: 'auto',
        /**
         * @type String
         * @default 200
         * @summary 标签页最大宽度
         */
        tabMaxWidth: 200,
        /**
         * @type Number
         * @default 0
         * @summary 选中的标签页索引
         */
        selected: 0,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否自动填充
         */
        autoFit: false,
        /**
         * @type Boolean
         * @default true
         * @summary 指示组件是否显示边框
         */
        border: true,
        /**
         * @type Number
         * @default 0
         * @summary 最大标签数
         */
        maxTabNumber: 0,

        /**
         * 值可为click(鼠标点击切换), mouseover(鼠标滑过切换)
         * @type String
         * @default click
         * @summary 页签切换的模式
         */
        switchMode: 'click',
        /**
         * @type Boolean
         * @default true
         * @summary 是否自动循环切换页签
         */
        autoPlay: false,
        /**
         * @type Number
         * @default 2000
         * @summary 自动切换间隔时间
         */
        autoPlayTime: 2000,
        /**
         * 是否懒加载，当该属性为true时，只有在页签被单击选中时才尝试加载标签页正文区。
         */
        /**
         * @type Boolean
         * @default false
         * @summary 是否延迟加载
         */
        lazyLoad: false,
        /**
         * @type String
         * @default top
         * @summary 标签页位置
         */
        tabPosition: 'top',
        /**
         * @type Number
         * @default 100
         * @summary 滚动的步长
         */
        scrollIncrement: 100,
        /**
         * @type Number
         * @default 400
         * @summary 滚动持续时间
         */
        scrollDuration: 400,
        /**
         * @type Boolean
         * @default false
         * @summary 是否启用右击菜单
         */
        enableContextMenu: false,
        /**
         * @type Array
         * @default [
         {id: 1, icon: 'update', label: '刷新标签'},
         {id: 2, icon: 'close', label: '关闭标签'},
         {id: 3, icon: 'closeo', label: '关闭其他'},
         {id: 4, icon: 'closea', label: '关闭所有'}
         ]
         * @summary 右键菜单数据，支持自定义(1~4为系统菜单ID)，自定义事件为click,{id: 5, icon: 'closea', label: '关闭所有',onSelect:function(item,triggerData){alert(item.id)}})
         */
        contextData: [
            {id: 1, icon: 'update', label: '刷新标签'},
            {id: 2, icon: 'close', label: '关闭标签'},
            {id: 3, icon: 'closeo', label: '关闭其他'},
            {id: 4, icon: 'closea', label: '关闭所有'}
        ],
        /**
         * @summary 在加载时触发的方法。
         * @event
         * @name uiTabs#onLoad
         * @param id {String} 所选标签页的id
         * @default emptyFn
         */
        onLoad: function (panel) {
        },
        /**
         * @summary 在选择标签页时触发的方法。
         * @event
         * @name uiTabs#onSelect
         * @param id {String} 所选标签页的id
         * @param index {Number} 所选标签页的索引
         * @default emptyFn
         */
        onSelect: function (id, index) {
        },
        /**
         * @summary 取消选择标签页时触发的方法。
         * @event
         * @name uiTabs#onUnselect
         * @param id {String} 所选标签页的id
         * @param index {Number} 所选标签页的索引
         * @default emptyFn
         */
        onUnselect: function (id, index) {
        },
        /**
         * @summary 在关闭标签页之前触发的方法。
         * @event
         * @name uiTabs#onBeforeClose
         * @param id {String} 所选标签页的id
         * @param index {Number} 所选标签页的索引
         * @default emptyFn
         */
        onBeforeClose: function (id, index) {
        },
        /**
         * @summary 在关闭标签页时触发的方法。
         * @event
         * @name uiTabs#onClose
         * @param id {String} 所选标签页的id
         * @param index {Number} 所选标签页的索引
         * @default emptyFn
         */
        onClose: function (id, index) {
        },
        /**
         * @summary 在添加标签页时触发的方法。
         * @event
         * @name uiTabs#onAdd
         * @param id {String} 所选标签页的id
         * @param index {Number} 所选标签页的索引
         * @default emptyFn
         */
        onAdd: function (id, index) {
        },
        /**
         * @summary 在更新标签页时触发的方法。
         * @event
         * @name uiTabs#onUpdate
         * @param id {String} 所选标签页的id
         * @param index {Number} 所选标签页的索引
         * @default emptyFn
         */
        onUpdate: function (id, index) {
        },
        /**
         * @summary 标签页右击时触发的方法。
         * @event
         * @name uiTabs#onContextMenu
         * @param e {String}
         * @param id {String} 所选标签页的id
         * @param index {Number} 所选标签页的索引
         * @default emptyFn
         */
        onContextMenu: function (e, id, index) {
        }
    };

    /**
     * 初始化
     * @param target
     * @private
     */
    var _init = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var tabs = $.data(target[0], _cacheName).tabs;
        target.setElemID();
        var targetID = target.getElemID();
        target.addClass('ui_tabs');
        var divs = target.children('div');
        target.empty();
        var reg = new RegExp('({tabs})', 'g');
        target.append($($.uiTemplate.tabs.html.replace(reg, targetID)).html());
        var panels = $.getByParentID(targetID, $.uiTemplate.tabs.panels);
        divs.each(function (index, value) {
            this.id = targetID + '-' + $.uiTemplate.tabs.panels + '-' + index;
            var pal = $(this);
            pal.appendTo(panels);
            var opts = $.extend({}, pal.parseUIConfig(), {
                selected: (pal.attr('selected') ? true : undefined)
            });
            tabs.push(pal);
            _createTab(target, pal, opts);
        });
        $.getByParentID(targetID, $.uiTemplate.tabs.headerLeft)
            .add($.getByParentID(targetID, $.uiTemplate.tabs.headerRight))
            .hover(
                function () {
                    $(this).addClass('ui_tabs_scroller_over');
                },
                function () {
                    $(this).removeClass('ui_tabs_scroller_over');
                }
            );
        target.bind("_resize", function () {
            var opts = $.data(target[0], _cacheName).options;
            if (opts.autoFit == true) {
                _setSize(target);
                _setSelectedSize(target);
            }
        });
        _contextMenu(target);
    };

    var _createTab = function (target, pal, palOptions) {
        var state = $.data(target[0], _cacheName);
        palOptions = palOptions || {};
        var targetID = target.getElemID();
        palOptions = $.extend(true, {}, {
            border: false,
            padding: '0px',
            closed: true,
            showHeader: false,
            showBtnBar: false,
            draggable: false,
            resizable: false,
            maximizable: false,
            collapsible: false,
            // 解决panel内容被加载两次的问题
            //content: pal.html(),
            onLoad: function () {
                if (palOptions.onLoad) {
                    palOptions.onLoad.call(this, arguments);
                }
                state.options.onLoad.call(target, $(this));
            }
        }, palOptions);
        var tabs = $.getByParentID(targetID, $.uiTemplate.tabs.headerTabs);
        var reg = new RegExp('({tab})', 'g');
        if (palOptions.id != undefined && palOptions.id != '') {
            pal[0].id = palOptions.id;
        } else {
            palOptions.id = pal[0].id;
        }
        palOptions.tab = $($.uiTemplate.tabs.tabHtml.replace(reg, pal[0].id)).appendTo(tabs);
        _updateTab(target, {tab: pal, options: palOptions});
    };

    /**
     *更新标签页
     * @param target
     * @param param
     */
    var _updateTab = function (target, param, update) {
        update = update == undefined ? false : update;
        var selectHis = $.data(target[0], _cacheName).selectHis;
        var pal = param.tab;
        var palID = pal[0].id;
        var palOptions = param.options;
        var oldID = '';
        try {
            var oldOpts = pal.uiPanel('options');
            oldID = oldOpts.id;
            palOptions = $.extend(oldOpts, palOptions);
        } catch (e) {
            oldID = palOptions.id;
        }
        if (update) {
            pal.uiPanel('refresh', pal.uiPanel('options').url);
        } else {
            pal.uiPanel(palOptions);
        }
        var opts = pal.uiPanel('options');
        var tab = opts.tab;

        var tab_title = $.getByParentID(palID, $.uiTemplate.tabs.tab_linkTitle);
        var tab_icon = $.getByParentID(palID, $.uiTemplate.tabs.tab_linkIcon);
        var tab_close = $.getByParentID(palID, $.uiTemplate.tabs.tab_close);
        tab_title.html(opts.title);
        tab.attr('title', opts.title);
        if (opts.closable) {
            if (tab_close.length == 0) {
                $('<a id="' + palID + '-' + $.uiTemplate.tabs.tab_close + '" href="javascript:void(0)" class="ui_tab_close"></a>').appendTo(tab);
            }
        } else {
            if (tab_close.length > 0) {
                tab_close.remove();
            }
        }
        if (opts.fontIcon && !_IEunder6) {
            opts.fontIcon.size = opts.fontIcon.size || 16;
            opts.fontIcon.color = opts.fontIcon.color || 'inherit';
            tab_icon.addClass('ui_panel_fontIcon fa').addClass(opts.fontIcon.icon)
                .css({color: opts.fontIcon.color, fontSize: opts.fontIcon.size});
        } else {
            if (opts.icon) {
                if(opts.icon.indexOf('.')>0){
                    tab_icon.addClass('icon').html("<img class='noBorder' src='"+opts.icon+"'>");
                }else{
                    tab_icon.addClass('icon ' + $.uiTemplate.iconStyle_Pre + opts.icon);
                }
            } else {
                tab_icon.removeClass();
            }
        }
        if (oldID != opts.id) {
            for (var i = 0; i < selectHis.length; i++) {
                if (selectHis[i] == oldID) {
                    selectHis[i] = opts.id;
                }
            }
        }
        $.data(target[0], _cacheName).options.onUpdate.call(target, opts.id, _getTabIndex(target, pal));
    };


    var _setProperties = function (target) {
        var opts = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        var header = $.getByParentID(targetID, $.uiTemplate.tabs.header);
        var panels = $.getByParentID(targetID, $.uiTemplate.tabs.panels);

        header.removeClass('ui_tabs_header-top ui_tabs_header-bottom ui_tabs_header-left ui_tabs_header-right');
        panels.removeClass('ui_tabs_panels-top ui_tabs_panels-bottom ui_tabs_panels-left ui_tabs_panels-right');
        if (opts.tabPosition == 'top') {
            header.insertBefore(panels);
            header.addClass('ui_tabs_header-top');
            panels.addClass('ui_tabs_panels-bottom');
        } else if (opts.tabPosition == 'bottom') {
            header.insertAfter(panels);
            header.addClass('ui_tabs_header-bottom');
            panels.addClass('ui_tabs_panels-top');
        } else if (opts.tabPosition == 'left') {
            header.addClass('ui_tabs_header-left');
            panels.addClass('ui_tabs_panels-right');
        } else if (opts.tabPosition == 'right') {
            header.addClass('ui_tabs_header-right');
            panels.addClass('ui_tabs_panels-left');
        }

        if (opts.border == true) {
            header.removeClass('ui_tabs_header_noborder');
            panels.removeClass('ui_tabs_panels_noborder');
        } else {
            header.addClass('ui_tabs_header_noborder');
            panels.addClass('ui_tabs_panels_noborder');
        }
    };

    var _setSize = function (target) {
        var state = $.data(target[0], _cacheName);
        var opts = state.options;
        if (opts.autoFit) {
            target.autoFit(true, false);
        } else {
            target.width(opts.width).height(opts.height);
        }
        var targetID = target.getElemID();
        var header = $.getByParentID(targetID, $.uiTemplate.tabs.header);
        var panels = $.getByParentID(targetID, $.uiTemplate.tabs.panels);
        var headerCenter = $.getByParentID(targetID, $.uiTemplate.tabs.headerCenter);
        var ul = $.getByParentID(targetID, $.uiTemplate.tabs.headerTabs);
        for (var index = 0; index < state.tabs.length; index++) {
            var pal = state.tabs[index];
            var pal_opts = pal.uiPanel('options');
            var tab_title = $.getByParentID(pal.getElemID(), $.uiTemplate.tabs.tab_link);
            var tab_title_t = $.getByParentID(pal.getElemID(), $.uiTemplate.tabs.tab_linkTitle);
            var iconw = 0;
            var closew = 0;
            if (pal_opts.icon != '' || (pal_opts.fontIcon != null && !_IEunder6)) {
                iconw = 20;
                tab_title_t.css({left: 20});
            }
            if (pal_opts.closable) {
                closew = 5;
            }
            var tabW = parseInt(opts.tabWidth);
            opts.tabWidth=opts.tabWidth+'';
            if (opts.tabWidth.indexOf("%") > 0) {
                tabW = target.width() * tabW / 100;
            }
            if (tabW && tabW > 0) {
                pal_opts.tabWidth = tabW;
                tab_title.width(tabW);
                tab_title_t.outerWidth(tab_title.width() - iconw - closew);
            } else {
                var titleW = tab_title_t.outerWidth();
                if (_IEunder9) {
                    titleW = tab_title_t.text().length * 14;
                }
                var w = titleW + iconw + closew;
                if (w > opts.tabMaxWidth) {
                    w = opts.tabMaxWidth;
                    tab_title_t.outerWidth(opts.tabMaxWidth - iconw - closew);
                }
                pal_opts.tabWidth = w;
                tab_title.width(w);
            }
        }
        if (opts.tabPosition == 'left' || opts.tabPosition == 'right') {
            header.outerWidth(opts.headerWidth);
            panels.outerWidth(target.width() - header.outerWidth());
            panels.outerHeight(target.height());
            header.add(panels).outerHeight(target.height());
            headerCenter.outerWidth(header.width()).outerHeight(target.height());
            ul.outerWidth(headerCenter.width());
        } else {
            var scroller_link = $.getByParentID(targetID, $.uiTemplate.tabs.headerLeft)
                .add($.getByParentID(targetID, $.uiTemplate.tabs.headerRight));
            header.outerWidth(target.width());
            scroller_link.show();
            ul.outerHeight(opts.tabHeight).css('width', '');
            _setScrollers(target);
            panels.outerHeight(target.height() - header.outerHeight());
            panels.outerWidth(target.width());
        }
    };


    /**
     * 是否显示tab左右滚动链接
     * @param target
     * @private
     */
    var _setScrollers = function (target) {
        var opts = $.data(target[0], _cacheName).options;
        if (opts.tabPosition == 'left' || opts.tabPosition == 'right') {
            return;
        }
        var targetID = target.getElemID();
        var header = $.getByParentID(targetID, $.uiTemplate.tabs.header);
        var headerCenter = $.getByParentID(targetID, $.uiTemplate.tabs.headerCenter);
        var sLeft = $.getByParentID(targetID, $.uiTemplate.tabs.headerLeft);
        var sRight = $.getByParentID(targetID, $.uiTemplate.tabs.headerRight);
        var headerTabs = $.getByParentID(targetID, $.uiTemplate.tabs.headerTabs);

        var tHeight = header.outerHeight();
        var tabsWidth = 0;
        headerTabs.children('li').each(function () {
            tabsWidth += $(this).outerWidth(true);
        });
        var cWidth = header.width();

        if (tabsWidth > cWidth) {
            sLeft.add(sRight).show().outerHeight(tHeight);
            headerCenter.css({
                marginLeft: sLeft.outerWidth(),
                marginRight: sRight.outerWidth(),
                width: cWidth - sLeft.outerWidth() - sRight.outerWidth()
            });
        } else {
            sLeft.add(sRight).hide();
            headerCenter.css({
                marginLeft: 0,
                marginRight: 0,
                width: cWidth
            });
        }
    };

    /**
     * 设置选中的标签页面板的大小
     * @param target
     * @private
     */
    var _setSelectedSize = function (target) {
        var opts = $.data(target[0], _cacheName).options;
        var tab = _getSelectedTab(target);
        if (tab) {
            var panels = $.getByParentID(target.getElemID(), $.uiTemplate.tabs.panels);
            var width = panels.width();
            var height = panels.height();
            tab.uiPanel('resize', {
                width: width,
                height: height
            });
        }
    };

    var _bindEvents = function (target) {
        var state = $.data(target[0], _cacheName);
        var opts = state.options;
        var targetID = target.getElemID();
        var header = $.getByParentID(targetID, $.uiTemplate.tabs.header);
        var ul = $.getByParentID(targetID, $.uiTemplate.tabs.headerTabs);
        header.unbind().bind(opts.switchMode, function (e) {
            if (e.target.id == header[0].id || e.target.id == ul[0].id) {
            } else if (e.target.id == $.getIDByParentID(targetID, $.uiTemplate.tabs.headerLeft)) {
                target.uiTabs('scrollBy', -opts.scrollIncrement);
            } else if (e.target.id == $.getIDByParentID(targetID, $.uiTemplate.tabs.headerRight)) {
                target.uiTabs('scrollBy', opts.scrollIncrement);
            } else {
                var evTarget = $(e.target);
                var li = evTarget.closest('li');
                if (li.hasClass('tabs-disabled')) {
                    return;
                }
                if (li.length) {
                    var tabIndex = getLiIndex(li);
                    if (evTarget.hasClass('ui_tab_close')||e.button==1) {
                        _closeTab(target, tabIndex);
                        return;
                    }
                    var popts = state.tabs[tabIndex].uiPanel('options');
                    if (popts.collapsible) {
                        popts.closed ? _selectTab(target, tabIndex) : _unselectTab(target, tabIndex);
                    } else {
                        _selectTab(target, tabIndex);
                    }
                }
            }
        });
        if (opts.enableContextMenu) {
            header.unbind('contextmenu').bind('contextmenu', function (e) {
                var li = $(e.target).closest('li');
                if (li.hasClass('tabs-disabled')) {
                    return;
                }
                if (li.length) {
                    var tabIndex = getLiIndex(li);
                    var tab = target.uiTabs('getTab', tabIndex);
                    var menu = $.getByParentID(targetID, $.uiTemplate.tabs.tabContextMenu);
                    var mId = menu.attr('id');
                    var mOpt = tab.uiPanel('options');

                    opts.onContextMenu.call(target, e, li[0].id, tabIndex);
                    menu.uiMenu('show', {triggerObject: e, triggerData: {tabIndex: tabIndex, tabID: tab[0].id}});
                    // 没有Iframe时禁用刷新菜单项
                    if (!mOpt.iniframe) {
                        menu.uiMenu('disableItem', mId + '_1');
                    } else {
                        menu.uiMenu('enableItem', mId + '_1');
                    }
                    if (!mOpt.closable) {
                        menu.uiMenu('disableItem', mId + '_2');
                    } else {
                        menu.uiMenu('enableItem', mId + '_2');
                    }
                }
            });
        }
        function getLiIndex(li) {
            var index = 0;
            ul.children('li').each(function (i) {
                if (li[0].id == this.id) {
                    index = i;
                    return false;
                }
            });
            return index;
        }
    };

    var _addTab = function (target, options) {
        var opts = $.data(target[0], _cacheName).options;
        var tabs = $.data(target[0], _cacheName).tabs;
        if (options.selected == undefined) options.selected = true;

        if (options.id != undefined && options.id != '') {
            var tab = _getTab(target, options.id);
            if (tab) {
                _selectTab(target, options.id);
                return;
            }
        } else {
            options.id = guidGenerator();
        }
        var panel = $('<div></div>').appendTo($.getByParentID(target.getElemID(), $.uiTemplate.tabs.panels));
        tabs.push(panel);
        _createTab(target, panel, options);
        opts.onAdd.call(target, options.id, tabs.length - 1);
        _setSize(target);
        if (options.selected) {
            _selectTab(target, tabs.length - 1);
        }
    };

    /**
     * 关闭指定标签页
     * @param target
     * @param which
     * @private
     */
    var _closeTab = function (target, which) {
        var opts = $.data(target[0], _cacheName).options;
        var tabs = $.data(target[0], _cacheName).tabs;
        var selectHis = $.data(target[0], _cacheName).selectHis;

        if (!_exists(target, which)) return;

        var tab = _getTab(target, which);
        var id = tab[0].id;
        var index = tab[0].index;

        if (opts.onBeforeClose.call(target, id, index) == false) return;

        tabs.splice(index, 1);
        tab.uiPanel('options').tab.remove();
        tab.uiPanel('destroy');
        opts.onClose.call(target, id, index);
        _setSize(target);
        for (var i = 0; i < selectHis.length; i++) {
            if (selectHis[i] == id) {
                selectHis.splice(i, 1);
                i--;
            }
        }
        var hisID = selectHis.pop();
        if (hisID) {
            _selectTab(target, hisID);
        } else {
            _selectTab(target, 0);
        }
    };

    /**
     * 获取指定的标签页
     */
    var _getTab = function (target, which, removeit) {
        var tabs = $.data(target[0], _cacheName).tabs;
        if (typeof which == 'number') {
            if (which < 0 || which >= tabs.length) {
                return null;
            } else {
                var tab = tabs[which];
                if (removeit) {
                    tabs.splice(which, 1);
                }
                tab[0].index = which;
                return tab;
            }
        }
        for (var i = 0; i < tabs.length; i++) {
            var tab = tabs[i];
            if (tab[0].id == which) {
                if (removeit) {
                    tabs.splice(i, 1);
                }
                tab[0].index = i;
                return tab;
            }
        }
        return null;
    };

    var _getTabIndex = function (target, tab) {
        var tabs = $.data(target[0], _cacheName).tabs;
        for (var i = 0; i < tabs.length; i++) {
            if (tabs[i][0].id == $(tab)[0].id) {
                return i;
            }
        }
        return -1;
    };

    var _getSelectedTab = function (target) {
        var tabs = $.data(target[0], _cacheName).tabs;
        for (var i = 0; i < tabs.length; i++) {
            var tab = tabs[i];
            if (tab.uiPanel('options').closed == false) {
                return tab;
            }
        }
        return null;
    };

    /**
     * 设置第一个选中的标签页
     * @param target
     * @private
     */
    var _doFirstSelect = function (target) {
        var state = $.data(target[0], _cacheName)
        _selectTab(target, state.options.selected);
    };

    var _selectTab = function (target, which) {
        var state = $.data(target[0], _cacheName);
        var opts = state.options;
        var tabs = state.tabs;
        var selectHis = state.selectHis;

        if (tabs.length == 0) {
            return;
        }

        var panel = _getTab(target, which);
        if (!panel) {
            return;
        }
        var selected = _getSelectedTab(target);
        if (selected) {
            if (panel[0].id == selected[0].id) {
                return;
            }
            _unselectTab(target, _getTabIndex(target, selected));
            if (!selected.uiPanel('options').closed) {
                return;
            }
        }

        panel.uiPanel('open');
        var palID = panel[0].id;
        selectHis.push(palID);
        var tab = panel.uiPanel('options').tab;
        tab.addClass('tabs_selected');

        var header = $.getByParentID(target.getElemID(), $.uiTemplate.tabs.header);
        var left = tab.position().left;
        var right = left + tab.outerWidth();
        if (left < 0 || right > header.width()) {
            var deltaX = left - (header.width() - tab.width()) / 2;
            $(target).uiTabs('scrollBy', deltaX);
        } else {
            $(target).uiTabs('scrollBy', 0);
        }

        _setSelectedSize(target);

        opts.onSelect.call(target, palID, _getTabIndex(target, panel));
    };

    var _unselectTab = function (target, which) {
        var state = $.data(target[0], _cacheName);
        var pal = _getTab(target, which);
        if (pal) {
            var opts = pal.uiPanel('options');
            if (!opts.closed) {
                pal.uiPanel('close');
                if (opts.closed) {
                    opts.tab.removeClass('tabs_selected');
                    state.options.onUnselect.call(target, pal[0].id, _getTabIndex(target, pal));
                }
            }
        }
    };

    /**
     * 判断标签页是否存在
     * @param target
     * @param which
     * @returns {boolean}
     * @private
     */
    var _exists = function (target, which) {
        return _getTab(target, which) != null;
    };
    var _contextMenu = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var targetID = target.getElemID();
        if (options.enableContextMenu) {
            var menu = $('<div id="' + $.getIDByParentID(targetID, $.uiTemplate.tabs.tabContextMenu) + '"></div>').appendTo(target);
            menu.uiMenu({
                contextMenu: true,
                minWidth: 120,
                maxWidth: 120,
                dataSource: options.contextData,
                onSelect: function (item, e) {
                    var triggerData = menu.uiMenu('options').triggerData;
                    var tabIndex = triggerData.tabIndex;
                    var tabID = triggerData.tabID;
                    switch (item.id) {
                        case 1:
                            target.uiTabs('select', tabIndex);
                            var tab = target.uiTabs('getSelected');
                            tab.uiPanel('refresh', tab.uiPanel('options').url);
                            break;
                        case 2:
                            target.uiTabs('close', tabIndex);
                            break;
                        case 3:
                            var tabs = target.uiTabs('tabs');
                            for (var i = 0; i < tabs.length; i++) {
                                var tab = tabs[i];
                                if (tabID != tab[0].id && tab.uiPanel('options').closable == true) {
                                    target.uiTabs('close', tab[0].id);
                                    i--;
                                }
                            }
                            break;
                        case 4:
                            var tabs = target.uiTabs('tabs');
                            for (var i = 0; i < tabs.length; i++) {
                                var tab = tabs[i];
                                if (tab.uiPanel('options').closable == true) {
                                    target.uiTabs('close', i);
                                    i--;
                                }
                            }
                            break;
                        default :
                            item.onSelect.call(target, item, triggerData);
                            break;
                    }
                    menu.uiMenu('hide');
                }
            });
        }
    };
})(jQuery);
